﻿/*
 * File Name:               UnityEngine.cs
 * 
 * Description:             冰淇淋
 * Author:                  zhangke <kris@zhanng.org>

 * Create Date:             2017/08/24
 */

using UnityEngine;

/// <summary>
/// 甜筒区域构造
/// </summary>
public struct IceCream
{
    public XVector2 center; // 圆心
    public XVector2 start; // 传球点
    public XNumber r; // 半径
    public XNumber s; // start-center距离
    public XNumber angle; // 锥型角度的一半
    public XNumber chordLength; // start-切点弦长

    public IceCream(XVector2 start, XVector2 center, XNumber r)
    {
        this.start = start;
        this.center = center;
        this.r = r;
        s = (center - start).magnitude;

        if (r > 0)
        {
            var rad = XIntMath.Asin(r / s);
            angle = XIntMath.Rad2Deg(rad);
            chordLength = XIntMath.Sqrt(XIntMath.Max(0, s * s - r * r));
        }
        else
        {
            angle = XNumber.zero;
            chordLength = s;
        }
    }

    public bool CheckIn(XVector2 point)
    {
        if (r <= 0)
            return false;

        if (s > r)
        {
            // 甜筒模式
            return checkCone(point);
        }
        else
        {
            // 披萨模式
            return checkPizza(point);
        }
    }

    // 甜筒
    private bool checkCone(XVector2 point)
    {
        if ((point - center).sqrMagnitude < r * r)
        {
            return true;
        }

        if ((point - start).sqrMagnitude < chordLength * chordLength)
        {
            var tmpAngle = Math2D.Angle_Dir2Dir((center - start), (point - start));
            if (XIntMath.Abs(tmpAngle) < angle)
            {
                return true;
            }
        }

        return false;
    }

    // 披萨
    private bool checkPizza(XVector2 point)
    {
        if ((point - center).sqrMagnitude > r * r)
        {
            return false;
        }

        var _angle = XVector2.Angle(point - start, start - center);
        if (_angle < 80)
            return false;

        return true;
    }

    public void Draw(XVector2 point)
    {
#if UNITY_EDITOR
        DebugExtension.DebugPoint(point.x0z);
        DebugExtension.DebugCircle(center.x0z, r);

        var point1 = start.x0z + (XQuaternion.AngleAxis(angle, XVector3.up) * (center.x0z - start.x0z)).normalized * chordLength;
        var point2 = start.x0z + (XQuaternion.AngleAxis(-angle, XVector3.up) * (center.x0z - start.x0z)).normalized * chordLength;

        Debug.DrawLine(start.x0z, point1, Color.white);
        Debug.DrawLine(start.x0z, point2, Color.white);
        DebugExtension.DebugArrow(start.x0z, center.x0z - start.x0z);

        if (point != null)
        {
            if (CheckIn(point))
            {
                Debug.DrawLine(start.x0z, point.x0z, Color.green);
                //Debug.DrawLine(center.x0z, point.x0z, Color.green);
            }
            else
            {
                Debug.DrawLine(start.x0z, point.x0z, Color.red);
                //Debug.DrawLine(center.x0z, point.x0z, Color.red);
            }
        }
#endif
    }
}